#ifndef LIBRARY_RFILE_H
#define LIBRARY_RFILE_H

#include "sortedlist.h"
#include "hashtable.h"

namespace Library
{

typedef SortedList<const String *>		ResourceFileList;
typedef ResourceFileList *				pResourceFileList;

typedef ListIterator<const String *>	ResourceFileListIterator;
typedef ResourceFileListIterator *		pResourceFileListIterator;

class PLIBEXP ResourceFile
{
	// namespace
	public:
		struct Format;

	// namespace
	private:
		struct Header;
		struct Index;
		friend class Library::ResourceFileWriter;

	public:
						ResourceFile();
		virtual			~ResourceFile();

		// ResourceFile originals
		virtual	bool8	open(Stream * fromStream);
		virtual	bool8	open(const String & filename);
		virtual	bool8	close();

		virtual	void *	get(const String & name);
        virtual	void *	get(const String & name, uint32 *punDataLength);  // kharmon.  01-09-07.  Adding ability to decompile rsc files.
		virtual	bool8	release(void * resource);

		virtual	uint32	resourceCount();
		virtual	pResourceFileList	resourceList();

	protected:
		virtual bool8	archive(Header * header);
		virtual pResourceEntry	createResourceEntry();

	protected:
		pStream		m_stream;
		HashTable<pResourceEntry> *	m_entries;

	// prohibited
	private:
		ResourceFile(ResourceFile &);
		ResourceFile & operator=(ResourceFile &);
};


//----------------------------------------------------------------------------


#define RF_MAGIC			"ResFile"

// NOTE: If you change RF_VERSION_MAJOR, *every* resource file *must* be
//       rebuilt (with a newly built resource compiler).
#define RF_VERSION_MAJOR	3
#define RF_VERSION_MINOR	0
#define RF_VERSION_PATCH	0
#define RF_VERSION_BUILD	0

/**
 * A structure which defines the on-disk file header.
 */
#define RH_DISKIMAGEFORMAT_VERSION_A		0
#define RH_CURRENT_DISKIMAGEFORMAT			RH_DISKIMAGEFORMAT_VERSION_A
struct Library::ResourceFile::Header
{
	uint8		m_magic[8];
	uint8		m_version[4];
	uint8		m_endian;
	uint8		m_dif_entry;			// dif == disk image format
	uint8		m_dif_index;
	uint8		m_dif_header;
	uint32		m_offset;				// Offset to ResourceFile::Indexes
	uint32		m_indices;				// Quantity of ResourceFile::Indexes
};

/**
 * A structure which defines the on-disk index headers.
 */
#define RI_DISKIMAGEFORMAT_VERSION_A		0
#define RI_CURRENT_DISKIMAGEFORMAT			RI_DISKIMAGEFORMAT_VERSION_A
struct Library::ResourceFile::Index
{
	char 		m_reserved[8];			// Deprecated fields.  Do not use.
	uint32		m_offset;				// Offset to ResourceEntry
	uint32		m_entries;				// Quantity of ResourceEntry
};


//----------------------------------------------------------------------------
// Documentation, prohibited methods (unimplemented)
//

/**
 * @fn Library::ResourceFile::File(Library::ResourceFile &)
 *
 * This method is reserved and unimplemented.  It has been defined for
 * Orthodox Canonical Form (OCF) compliance to prevent shallow object copies
 * from inadvertent use.
 */

/**
 * @fn Library::ResourceFile & Library::ResourceFile::operator=(Library::ResourceFile &)
 *
 * This method is reserved and unimplemented.  It has been defined for
 * Orthodox Canonical Form (OCF) compliance to prevent shallow object copies
 * from inadvertent use.
 */

}; // namespace Library

#endif

//
// vim: nowrap
//
